from typing import Optional

import yaml
from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings, SettingsConfigDict
from pathlib import Path

# Project Directories
ROOT = Path(__file__).resolve().parent.parent.parent


class ModelConfig(BaseModel):
    provider: str
    name: str
    temperature: float


class EmbeddingConfig(BaseModel):
    provider: str
    name: str


class VectorStoreConfig(BaseModel):
    persist_directory: str
    collection_name: str


class TextSplitterConfig(BaseModel):
    chunk_size: int
    chunk_overlap: int


class Config(BaseModel):
    llm: ModelConfig
    embedding: EmbeddingConfig
    vector_store: VectorStoreConfig
    text_splitter: TextSplitterConfig


def load_config(config_path: Path = ROOT / "app/configs/model_config.yaml") -> Config:
    with open(config_path, "r") as f:
        config_data = yaml.safe_load(f)
    return Config(**config_data)


class APISettings(BaseSettings):
    # Load from .env file
    model_config = SettingsConfigDict(env_file=str(ROOT / ".env"), env_file_encoding="utf-8")

    # API Keys
    OPENAI_API_KEY: str

    # API Base URL
    OPENAI_BASE_URL: Optional[str] = Field(default=None, alias="OPENAI_BASE_URL")


# Create a single instance of settings and config to be used across the application
api_settings = APISettings()
config = load_config()

# Set the API key in the environment for Langchain to pick it up
import os

os.environ["OPENAI_API_KEY"] = api_settings.OPENAI_API_KEY

if api_settings.OPENAI_BASE_URL:
    os.environ["OPENAI_BASE_URL"] = api_settings.OPENAI_BASE_URL